﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using CourseManager.Model.Data;

namespace CourseManager.Model
{
	public class Course
	{
	
		#region Static Part
		
		/// <summary>
		/// Cache of Course Objects used recently
		/// </summary>
		public static Hashtable CourseCache = new Hashtable();

		/// <summary>
		/// Empty the cache
		/// </summary>
		public static void ClearCache()
		{
			CourseCache.Clear();
		}

		public static Course get(string courseId, string tid)
		{
			string key = courseId + tid;
			return CourseCache.ContainsKey(key) ? 
						CourseCache[courseId] as Course : new Course(courseId, tid);
		}

		#endregion
		
		#region Properties

		public string CourseId { get; set; }
		public string TeacherId { get; set; }
		public string TId { get; set; }
		public string CourseName { get; set; }
		public double Credit { get; set; }
		public string TeacherName { get; set; }
		public string Time { get; set; }
		public string Campus { get; set; }
		public string Place { get; set; }
		public string Department { get; set; }
		public int? Capacity { get; set; }
		public object Tag;
		
		#endregion

		public List<TimeInfo> TimeInfoList;
		
		public Course()
		{
		}

		public String GetPrimaryKey()
		{
			return CourseId + " " + TId;
		}

		public Course(String pk)
		{
			string[] values = pk.Split(' ');
			string courseId = values[0];
			string tId = values[1];

			Tab_Course course = CourseDAO.FindByIdWithoutTName(courseId, tId);
			CourseName = course.courseName;
			TId = tId;
			CourseId = course.courseId;
			TeacherId = course.teacherId;
			Credit = course.credit;
			Time = course.time;
			Capacity = course.capacity;
			Campus = course.campus;
			Place = course.place;
			Department = course.dept;
			TeacherName = TeacherDAO.FindById(TeacherId).name;

			TimeInfoList = GetTimeInfoList();
		}

		public Course(string courseId, string tId)
		{
			Tab_Course course = CourseDAO.FindByIdWithoutTName(courseId, tId);
			CourseName = course.courseName;
			TId = tId;
			CourseId = course.courseId;
			TeacherId = course.teacherId;
			Credit = course.credit;
			Time = course.time;
			Capacity = course.capacity;
			Campus = course.campus;
			Place = course.place;
			Department = course.dept;
			TeacherName = TeacherDAO.FindById(TeacherId).name;

			TimeInfoList = GetTimeInfoList();
		}

		private List<TimeInfo> GetTimeInfoList()
		{
			var mc = new Regex(TimeInfo.Pattern).Matches(Time);
			Time = string.Empty;
			foreach (Match m in mc)
			{
				Time += m.Value + " ";
			}
			return (from Match m in mc select new TimeInfo(m.Value)).ToList();
		}
	
	
		public string FullDescribe
		{
			get
			{
				var sb = new StringBuilder(50);
				sb.Append("教师:").Append(TeacherName).Append(Environment.NewLine);
				sb.Append("时间:").Append(Time).Append(Environment.NewLine);
				sb.Append("地点:").Append(Place).Append(" ").Append(Place).Append(Environment.NewLine);
				return sb.ToString();
			}
		}

		public string SimpleDescribe
		{
			get
			{
				var sb = new StringBuilder(50);
				sb.Append(Tag).Append(".  ").Append(CourseName).Append(" - ").Append(TeacherName);
				return sb.ToString();
			}
		}
		
		public bool IntersectWith(Course other)
		{
			return (from timeInfo1 in TimeInfoList
			        from timeInfo2 in other.TimeInfoList
			        where timeInfo1.IntersectWith(timeInfo2)
			        select timeInfo1).Any();
		}

		public bool Equals(Course other)
		{
			if (ReferenceEquals(null, other))
				return false;
			if (ReferenceEquals(this, other))
				return true;
			return Equals(other.CourseId, CourseId) && Equals(other.TeacherId, TeacherId);
		}
		
		#region Override Methods

		public override bool Equals(object obj)
		{
			if (ReferenceEquals(null, obj)) return false;
			if (ReferenceEquals(this, obj)) return true;
			return obj.GetType() == typeof (Course) && Equals((Course) obj);
		}

		public override string ToString()
		{
			return SimpleDescribe;
		}


		public override int GetHashCode()
		{
			unchecked
			{
				return ((CourseId != null ? CourseId.GetHashCode() : 0)*397) 
						 ^ (TId != null ? TeacherId.GetHashCode() : 0);
			}
		}
		
		#endregion
	}
}